package com.cxx.purchasecharge.component.controller;

import java.util.ArrayList;
import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cxx.purchasecharge.component.bean.ActionResult;
import com.cxx.purchasecharge.component.bean.ActionResult.ActionResultStatus;
import com.cxx.purchasecharge.component.bean.DataGridRequestForm;
import com.cxx.purchasecharge.component.bean.GenericPagingResult;
import com.cxx.purchasecharge.component.bean.PaymentAccountBean;
import com.cxx.purchasecharge.component.bean.PaymentBean;
import com.cxx.purchasecharge.component.bean.SearchRequestForm;
import com.cxx.purchasecharge.component.utils.AjaxUtils;
import com.cxx.purchasecharge.component.utils.BeanConvertUtils;
import com.cxx.purchasecharge.component.utils.ComponentConstants;
import com.cxx.purchasecharge.component.utils.MessageProperties;
import com.cxx.purchasecharge.core.model.PaymentSearchForm;
import com.cxx.purchasecharge.core.model.persistence.Payment;
import com.cxx.purchasecharge.core.model.persistence.PaymentAccount;
import com.cxx.purchasecharge.dal.PaymentAccountDao;
import com.cxx.purchasecharge.dal.PaymentDao;

@Controller
@RequestMapping ("/paymentAccount")
public class PaymentAccountManager
{
    private static final Logger logger = Logger.getLogger (PaymentAccountManager.class);

    @Autowired
    private PaymentAccountDao paymentAccountDao;
    @Autowired
    private PaymentDao paymentDao;

    @RequestMapping (value = "/")
    public String redirectToPaymentAccountManagement (ModelMap model)
    {
        return "paymentAccountManagement";
    }

    @RequestMapping (value = "/paymentAccountView")
    public String redirectToPaymentAccountView (ModelMap model)
    {
        return "paymentAccountView";
    }

    @RequestMapping (value = "/orderProfitView")
    public String redirectToOrderProfitView (ModelMap model)
    {
        return "orderProfitView";
    }

    @RequestMapping (value = "/checkExistByName", method = RequestMethod.POST)
    public @ResponseBody
    String checkExistByName (@RequestParam String paymentAccountId, @RequestParam String name)
    {
        if (StringUtils.isBlank (paymentAccountId))
        {
            // new
            PaymentAccount obj = paymentAccountDao.findByName (name);
            if (null != obj)
            {
                return "false";
            }
        }
        else
        {
            // edit
            long id = Long.parseLong (paymentAccountId);
            PaymentAccount paymentAccount = paymentAccountDao.findByName (name);
            if (null != paymentAccount && paymentAccount.getId () != id)
            {
                return "false";
            }
        }

        return "true";
    }

    @RequestMapping (value = "/checkExistByNumber", method = RequestMethod.POST)
    public @ResponseBody
    String checkExistByNumber (@RequestParam String paymentAccountId, @RequestParam String number)
    {
        if (StringUtils.isBlank (paymentAccountId))
        {
            // new
            PaymentAccount obj = paymentAccountDao.findByNumber (number);
            if (null != obj)
            {
                return "false";
            }
        }
        else
        {
            // edit
            long id = Long.parseLong (paymentAccountId);
            PaymentAccount paymentAccount = paymentAccountDao.findByNumber (number);
            if (null != paymentAccount && paymentAccount.getId () != id)
            {
                return "false";
            }
        }

        return "true";
    }

    @RequestMapping (value = "/getAllAccount", method = RequestMethod.POST)
    public @ResponseBody
    String getPaymentAccounts (DataGridRequestForm dataGridRequestForm)
    {
        List <PaymentAccount> units = (List <PaymentAccount>) paymentAccountDao.findAll ();

        JSONArray jsonObject = JSONArray.fromObject (units);
        return jsonObject.toString ();
    }

    @RequestMapping (value = "/newPaymentAccount", method = RequestMethod.POST)
    public @ResponseBody
    String addPaymentAccount (PaymentAccountBean paymentAccountBean, BindingResult bindingResult)
    {
        if (bindingResult.hasErrors ())
        {
            logger.error (bindingResult.getAllErrors ());
            ActionResult ar = ActionResult.badRequest ()
                                          .withMessage (MessageProperties.getConfig (ComponentConstants.GENERIC_MSG_REQUEST_ARGS_ERROR))
                                          .build ();
            return AjaxUtils.getJsonObject (ar);
        }
        else
        {
            ActionResult ar = ActionResult.createActionResult ().build ();
            try
            {
                paymentAccountDao.save (BeanConvertUtils.paymentAccountBean2PaymentAccount (paymentAccountBean));
                ar = ActionResult.ok ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_ADD_SUCCESS,
                                                                                     ComponentConstants.MSG_PAYMENT_TYPE))
                                 .build ();
            }
            catch (Exception e)
            {
                logger.error (e.getMessage (), e);
                ar = ActionResult.serverError ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_ADD_FAIL,
                                                                                     ComponentConstants.MSG_PAYMENT_TYPE))
                                 .build ();
            }
            return AjaxUtils.getJsonObject (ar);
        }
    }

    @RequestMapping (value = "/updatePaymentAccount", method = RequestMethod.POST)
    public @ResponseBody
    String updatePaymentAccount (PaymentAccountBean paymentAccountBean, BindingResult bindingResult)
    {
        if (bindingResult.hasErrors ())
        {
            logger.error (bindingResult.getAllErrors ());
            ActionResult ar = ActionResult.badRequest ()
                                          .withMessage (MessageProperties.getConfig (ComponentConstants.GENERIC_MSG_REQUEST_ARGS_ERROR))
                                          .build ();
            return AjaxUtils.getJsonObject (ar);
        }
        else
        {
            ActionResult ar = ActionResult.createActionResult ().build ();
            try
            {
                paymentAccountDao.save (BeanConvertUtils.paymentAccountBean2PaymentAccount (paymentAccountBean));
                ar = ActionResult.ok ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_UPDATE_SUCCESS,
                                                                                     ComponentConstants.MSG_PAYMENT_TYPE))
                                 .build ();
            }
            catch (Exception e)
            {
                logger.error (e.getMessage (), e);
                ar = ActionResult.serverError ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_UPDATE_FAIL,
                                                                                     ComponentConstants.MSG_PAYMENT_TYPE))
                                 .build ();
            }
            return AjaxUtils.getJsonObject (ar);
        }
    }

    @RequestMapping (value = "/delPaymentAccount", method = RequestMethod.POST)
    public @ResponseBody
    String deletePaymentAccount (@RequestParam String ids)
    {
        if (null != ids && ids.trim ().length () > 0)
        {
            List <PaymentAccount> paymentAccounts = new ArrayList <PaymentAccount> ();
            PaymentAccount paymentAccount;
            if (ids.indexOf (";") != -1)
            {
                String[] idArr = ids.split (";");
                for (String typeId : idArr)
                {
                    paymentAccount = new PaymentAccount ();
                    paymentAccount.setId (Long.parseLong (typeId));
                    paymentAccounts.add (paymentAccount);
                }
            }
            else
            {
                paymentAccount = new PaymentAccount ();
                paymentAccount.setId (Long.parseLong (ids));
                paymentAccounts.add (paymentAccount);
            }

            ActionResult ar = ActionResult.createActionResult ().build ();
            try
            {
                paymentAccountDao.delete (paymentAccounts);
                ar = ActionResult.ok ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_DELETE_SUCCESS,
                                                                                     ComponentConstants.MSG_PAYMENT_TYPE))
                                 .build ();
            }
            catch (Exception e)
            {
                logger.error (e.getMessage (), e);
                ar = ActionResult.serverError ()
                                 .withMessage (MessageProperties.getConfigFormatted (ComponentConstants.GENERIC_MSG_DELETE_FAIL,
                                                                                     ComponentConstants.MSG_PAYMENT_TYPE))
                                 .build ();
            }
            return AjaxUtils.getJsonObject (ar);
        }
        else
        {
            logger.error (ActionResultStatus.BAD_REQUEST);
            ActionResult ar = ActionResult.badRequest ()
                                          .withMessage (MessageProperties.getConfig (ComponentConstants.GENERIC_MSG_REQUEST_ARGS_ERROR))
                                          .build ();
            return AjaxUtils.getJsonObject (ar);
        }
    }

    @RequestMapping (value = "/getPaymentAccountDetail", method = RequestMethod.POST)
    public @ResponseBody
    String getPaymentAccountDetail (DataGridRequestForm dataGridRequestForm, SearchRequestForm searchRequestForm)
    {
        PaymentSearchForm paymentSearchForm = BeanConvertUtils.searchRequestForm2PaymentSearchForm (searchRequestForm);
        int page = dataGridRequestForm.getPage () - 1;
        int size = dataGridRequestForm.getRows ();
        String sortField = (null == dataGridRequestForm.getSort ()) ? "paidDate" : "paidDate";
        String order = dataGridRequestForm.getOrder ();
        Pageable pageable = new PageRequest (page, size, new Sort ("asc".equalsIgnoreCase (order) ? Direction.ASC
                                                                                                 : Direction.DESC,
                                                                   sortField));

        Page <Payment> pagePayment = paymentDao.findPagePaymentBy (paymentSearchForm, pageable);

        GenericPagingResult <PaymentBean> payPagingResult = new GenericPagingResult <PaymentBean> ();
        payPagingResult.setRows (BeanConvertUtils.paymentList2PaymentBeanList (pagePayment.getContent ()));
        payPagingResult.setTotal (pagePayment.getTotalElements ());

        JSONObject jsonObject = JSONObject.fromObject (payPagingResult);
        return jsonObject.toString ();
    }

}
